﻿
namespace YiShop.System.Repositories
{
    public class SysMenuRepository : BaseRepository<SysMenu, SysMenuDto>
    {
        public SysMenuRepository(ISqlSugarRepository<SysMenu> sqlSugarRepository) : base(sqlSugarRepository)
        {
        }

        public override ISugarQueryable<SysMenu> Queryable(SysMenuDto dto)
        {
            return Repo.AsQueryable()
                .WhereIF(!string.IsNullOrEmpty(dto.Status), (m) => m.Status == dto.Status)
                .WhereIF(!string.IsNullOrEmpty(dto.MenuName), (m) => m.MenuName!.Contains(dto.MenuName!))
                .WhereIF(!string.IsNullOrEmpty(dto.Visible), (m) => m.Visible == dto.Visible)
                .WhereIF(dto.MenuTypes.Count > 0, (m) => dto.MenuTypes.Contains(m.MenuType!))
                .OrderBy(m => new { m.ParentId, m.OrderNum })
            ;
        }

        public override ISugarQueryable<SysMenuDto> DtoQueryable(SysMenuDto dto)
        {
            return Repo.AsQueryable()
                .LeftJoin<SysRoleMenu>((m, rm) => m.MenuId == rm.MenuId)
                .LeftJoin<SysUserRole>((m, rm, ur) => rm.RoleId == ur.RoleId)
                .LeftJoin<SysRole>((m, rm, ur, r) => rm.RoleId == r.RoleId)
                .WhereIF(!string.IsNullOrEmpty(dto.Status), (m, rm, ur, r) => m.Status == dto.Status)
                .WhereIF(!string.IsNullOrEmpty(dto.MenuName), (m, rm, ur, r) => m.MenuName!.Contains(dto.MenuName!))
                .WhereIF(!string.IsNullOrEmpty(dto.Visible), (m, rm, ur, r) => m.Visible == dto.Visible)
                .WhereIF(dto.UserId > 0, (m, rm, ur, r) => ur.UserId == dto.UserId)
                .WhereIF(dto.RoleId > 0, (m, rm, ur, r) => rm.RoleId == dto.RoleId)
                .WhereIF(!string.IsNullOrEmpty(dto.RoleStatus), (m, rm, ur, r) => r.Status == dto.RoleStatus)
                .WhereIF(dto.MenuTypes.Count > 0, (m) => dto.MenuTypes.Contains(m.MenuType!))
                .OrderBy(m => new { m.ParentId, m.OrderNum })
                .Select((m, rm, ur, r) => new SysMenuDto
                {
                    CreateBy = m.CreateBy,
                    CreateTime = m.CreateTime,
                    UpdateBy = m.UpdateBy,
                    UpdateTime = m.UpdateTime,

                    MenuId = m.MenuId,
                    ParentId = m.ParentId,
                    MenuName = m.MenuName,
                    Path = m.Path,
                    Component = m.Component,
                    Query = m.Query,
                    Visible = m.Visible,
                    Status = m.Status,
                    Perms = m.Perms,
                    IsFrame = m.IsFrame,
                    IsCache = m.IsCache,
                    MenuType = m.MenuType,
                    Icon = m.Icon,
                    OrderNum = m.OrderNum,
                }).Distinct();
        }

        /// <summary>
        /// 查询菜单
        /// </summary>
        public async Task<List<SysMenu>> SelectMenuTreeAll()
        {
            SysMenuDto dto = new() { Status = Status.Enabled, MenuTypes = ["M", "C"] };
            return await GetListAsync(dto);
        }

        /// <summary>
        /// 根据用户ID查询菜单
        /// </summary>
        public async Task<List<SysMenu>> SelectMenuTreeByUserId(long userId)
        {
            SysMenuDto dto = new() { UserId = userId, Status = Status.Enabled, RoleStatus = Status.Enabled };

            return await GetListAsync(dto);
        }

        internal Task<List<long>> SelectMenuListByRoleId(long roleId, bool isMenuCheckStrictly)
        {
            var queryable = Repo.AsQueryable()
                .LeftJoin<SysRoleMenu>((m, rm) => m.MenuId == rm.MenuId)
                .Where((m, rm) => rm.RoleId == roleId)
                .WhereIF(isMenuCheckStrictly, (m, rm) => SqlFunc.Subqueryable<SysMenu>()
                    .InnerJoin<SysRoleMenu>((sm, srm) => sm.MenuId == srm.MenuId && srm.RoleId == roleId)
                    .Where(sm => sm.ParentId == m.MenuId).NotAny())
                .OrderBy(m => new { m.ParentId, m.OrderNum });

            return queryable.Select(m => m.MenuId).ToListAsync();
        }
    }
}
